/**************************************************************************//**
 * @file           main.c
 * @version        V1.0
 * $Revision:      1 $
 * $Date:          2017/01/04 $
 * @brief          Main function
 * @Author         Jeffrey Kang
 * @ContactInfo    chkang@esmt.com.tw
 *
 * @note
 *
 * Copyright (C) 1998 Elite Semiconductor Memory Technology Corp.
 * All rights reserved.
 *
 ******************************************************************************/


#include <REG52.h>
#include "system_FE81001.h"


#define TMR  // TMR or PWM


volatile unsigned char cnt = 0;

/**
 * @brief       delay function
 *
 * @param       None
 *
 * @return      None
 *
 * @details     1. 
 */
void delay( void )
{
	unsigned int i;
	
	for( i = 0 ; i < 500 ; i++ ){}
}


/**
 * @brief       TMR2ISR function
 *
 * @param       None
 *
 * @return      None
 *
 * @details     1. 
 */
const void TMR2ISR (void) interrupt ISR_TMR2
{
	unsigned char int_stat;
	
	/* read interrupt status */
	int_stat = TMR2->int_stat;
	TMR2->int_stat = 0xFF;
	
	/*Toggle LED*/
	 PD3 = ~PD3;
	
	/* enable global interrupt */
	INTC->int_gmask = 0x01;
}


/**
 * @brief       TMR1ISR function
 *
 * @param       None
 *
 * @return      None
 *
 * @details     1. 
 */
const void TMR1ISR (void) interrupt ISR_TMR1
{
	unsigned char int_stat;
	
	/* read interrupt status */
	int_stat = TMR1->int_stat;
	TMR1->int_stat = 0xFF;
	
	/*Toggle LED*/
	 PD2 = ~PD2;
	
	/* enable global interrupt */
	INTC->int_gmask = 0x01;

}


/**
 * @brief       TMR0ISR function
 *
 * @param       None
 *
 * @return      None
 *
 * @details     1. 
 */
const void TMR0ISR (void) interrupt ISR_TMR0
{
	unsigned char int_stat;

	/* read interrupt status */
	   int_stat = TMR0->int_stat;
		TMR0->int_stat = 0xFF;			// Write 1 to Clear
	
		 PD1 = ~PD1;

	/* enable global interrupt */
		 INTC->int_gmask = 0x01;
}


/**
 * @brief       TMR2Init function
 *
 * @param       None
 *
 * @return      None
 *
 * @details     1. 
 */
void TMR2Init(void)
{
	
#ifdef TMR
	
	/* TMR2 control setting */
	Timer2_CH0_Mode(Mode_32bit_Timer);
	Timer2_CH1_Mode(Mode_32bit_Timer);
	
	/* TMR2 Ch0 reload setting*/
	TMR2->reload0[0] = 0x00;			// 32-bit Timers : Reload0_0 = 0x00 (0xF4240 -> 1,000,000) MSB
	TMR2->reload0[1] = 0x0F;			// 32-bit Timers : Reload0_1 = 0x0F (0xF4240 -> 1,000,000)
	TMR2->reload0[2] = 0x42;			// 32-bit Timers : Reload0_2 = 0x42 (0xF4240 -> 1,000,000)
	TMR2->reload0[3] = 0x40;			// 32-bit Timers : Reload0_3 = 0x40 (0xF4240 -> 1,000,000)	LSB
	
	/* TMR2 Ch1 reload setting*/
	TMR2->reload1[0] = 0x00;			// 32-bit Timers : Reload0_0 = 0x00 (0xF4240 -> 1,000,000) MSB
	TMR2->reload1[1] = 0x0F;			// 32-bit Timers : Reload0_1 = 0x0F (0xF4240 -> 1,000,000)
	TMR2->reload1[2] = 0x42;			// 32-bit Timers : Reload0_2 = 0x42 (0xF4240 -> 1,000,000)
	TMR2->reload1[3] = 0x40;			// 32-bit Timers : Reload0_3 = 0x40 (0xF4240 -> 1,000,000)	LSB
	
	/* interrupt enable setting */
	Timer2_Interrupt_Enable(Ch0_Timer0);
	
	/* timer start */
	Timer2_Start_Enable(Ch0_Timer0);
	
#else  // PWM

		/* TMR2 control setting */
	Timer2_CH0_Mode(Mode_PWM);
	Timer2_CH1_Mode(Mode_PWM);
	
	/* TMR2 Ch0 reload setting */
	TMR2->reload0[0] = 0x00;			//  PWM High Level Width - H_byte =  0x00(99)
	TMR2->reload0[1] = 0x63;			//	PWM High Level Width - L_byte  =  0x63(99)
	TMR2->reload0[2] = 0x00;			// 	PWM Low Level Width - H_byte  =  0x00(99)
	TMR2->reload0[3] = 0x63;			//  PWM Low Level Width - L_byte   =  0x63(99)

	/* TMR2 Ch1 reload setting */
	TMR2->reload1[0] = 0x03;			// 	PWM High Level Width - H_byte =  0x03(999)
	TMR2->reload1[1] = 0xE7;			//  PWM High Level Width - L_byte  =  0xE7(999)
	TMR2->reload1[2] = 0x03;			//  PWM Low Level Width - H_byte  =  0x03(999)
	TMR2->reload1[3] = 0xE7;			//  PWM Low Level Width - L_byte   =  0xE7(999)
	
	/* interrupt enable setting */
	
	/* timer start */
	Timer2_Start_Enable(Ch0_Timer3 | Ch1_Timer3);
	
#endif

}


/**
 * @brief       TMR1Init function
 *
 * @param       None
 *
 * @return      None
 *
 * @details     1. 
 */
void TMR1Init(void)
{
#ifdef TMR
	
	/* TMR1 control setting */
	Timer1_CH0_Mode(Mode_32bit_Timer);
	Timer1_CH1_Mode(Mode_32bit_Timer);
	
	/* TMR1 Ch0 reload setting*/
	TMR1->reload0[0] = 0x00;			// 32-bit Timers : Reload0_0 = 0x00 (0xF4240 -> 1,000,000) MSB
	TMR1->reload0[1] = 0x0F;			// 32-bit Timers : Reload0_1 = 0x0F (0xF4240 -> 1,000,000)
	TMR1->reload0[2] = 0x42;			// 32-bit Timers : Reload0_2 = 0x42 (0xF4240 -> 1,000,000)
	TMR1->reload0[3] = 0x40;			// 32-bit Timers : Reload0_3 = 0x40 (0xF4240 -> 1,000,000)	LSB
	
	/* TMR1 Ch1 reload setting*/
	TMR1->reload1[0] = 0x00;			// 32-bit Timers : Reload0_0 = 0x00 (0xF4240 -> 1,000,000) MSB
	TMR1->reload1[1] = 0x0F;			// 32-bit Timers : Reload0_1 = 0x0F (0xF4240 -> 1,000,000)
	TMR1->reload1[2] = 0x42;			// 32-bit Timers : Reload0_2 = 0x42 (0xF4240 -> 1,000,000)
	TMR1->reload1[3] = 0x40;			// 32-bit Timers : Reload0_3 = 0x40 (0xF4240 -> 1,000,000)	LSB
	
	/* interrupt enable setting */
	Timer1_Interrupt_Enable(Ch0_Timer0);
	
	/* timer start */
	Timer1_Start_Enable(Ch0_Timer0);
	
#else  // PWM

		/* TMR1 control setting */
	Timer1_CH0_Mode(Mode_PWM);
	Timer1_CH1_Mode(Mode_PWM);
	
	/* TMR1 Ch0 reload setting */
	TMR1->reload0[0] = 0x00;			//  PWM High Level Width - H_byte =  0x00(99)
	TMR1->reload0[1] = 0x63;			//	PWM High Level Width - L_byte  =  0x63(99)
	TMR1->reload0[2] = 0x00;			// 	PWM Low Level Width - H_byte  =  0x00(99)
	TMR1->reload0[3] = 0x63;			//  PWM Low Level Width - L_byte   =  0x63(99)

	/* TMR1 Ch1 reload setting */
	TMR1->reload1[0] = 0x03;			// 	PWM High Level Width - H_byte =  0x03(999)
	TMR1->reload1[1] = 0xE7;			//  PWM High Level Width - L_byte  =  0xE7(999)
	TMR1->reload1[2] = 0x03;			//  PWM Low Level Width - H_byte  =  0x03(999)
	TMR1->reload1[3] = 0xE7;			//  PWM Low Level Width - L_byte   =  0xE7(999)
	
	/* interrupt enable setting */
	
	/* timer start */
	Timer1_Start_Enable(Ch0_Timer3 | Ch1_Timer3);
	
#endif
}


/**
 * @brief       TMR0Init function
 *
 * @param       None
 *
 * @return      None
 *
 * @details     1. 
 */
void TMR0Init(void)
{
#ifdef TMR
	
	/* TMR0 control setting */
	Timer0_CH0_Mode(Mode_32bit_Timer);
	Timer0_CH1_Mode(Mode_32bit_Timer);
	
	/* TMR0 Ch0 reload setting*/
	TMR0->reload0[0] = 0x00;			// 32-bit Timers : Reload0_0 = 0x00 (0xF4240 -> 1,000,000) MSB
	TMR0->reload0[1] = 0x0F;			// 32-bit Timers : Reload0_1 = 0x0F (0xF4240 -> 1,000,000)
	TMR0->reload0[2] = 0x42;			// 32-bit Timers : Reload0_2 = 0x42 (0xF4240 -> 1,000,000)
	TMR0->reload0[3] = 0x40;			// 32-bit Timers : Reload0_3 = 0x40 (0xF4240 -> 1,000,000)	LSB
	
	/* TMR0 Ch1 reload setting*/
	TMR0->reload1[0] = 0x00;			// 32-bit Timers : Reload1_0 = 0x00 (0xF4240 -> 1,000,000) MSB
	TMR0->reload1[1] = 0x0F;			// 32-bit Timers : Reload1_1 = 0x0F (0xF4240 -> 1,000,000)
	TMR0->reload1[2] = 0x42;			// 32-bit Timers : Reload1_2 = 0x42 (0xF4240 -> 1,000,000)
	TMR0->reload1[3] = 0x40;			// 32-bit Timers : Reload1_3 = 0x40 (0xF4240 -> 1,000,000) LSB
	
	/* interrupt enable setting */
	Timer0_Interrupt_Enable(Ch0_Timer0);
	
	/* timer start */
	Timer0_Start_Enable(Ch0_Timer0);
	
#else // PWM

	/* TMR0 control setting */
	Timer0_CH0_Mode(Mode_PWM);
	Timer0_CH1_Mode(Mode_PWM);
	
	/* TMR0 Ch0 reload setting */
	TMR0->reload0[0] = 0x00;			//  PWM High Level Width - H_byte =  0x00(99)
	TMR0->reload0[1] = 0x63;			//	PWM High Level Width - L_byte  =  0x63(99)
	TMR0->reload0[2] = 0x00;			// 	PWM Low Level Width - H_byte  =  0x00(99)
	TMR0->reload0[3] = 0x63;			//  PWM Low Level Width - L_byte   =  0x63(99)

	/* TMR0 Ch1 reload setting */
	TMR0->reload1[0] = 0x03;			// 	PWM High Level Width - H_byte =  0x03(999)
	TMR0->reload1[1] = 0xE7;			//  PWM High Level Width - L_byte  =  0xE7(999)
	TMR0->reload1[2] = 0x03;			//  PWM Low Level Width - H_byte  =  0x03(999)
	TMR0->reload1[3] = 0xE7;			//  PWM Low Level Width - L_byte   =  0xE7(999)
	
	/* interrupt enable setting */
	
	/* timer start */
	Timer0_Start_Enable(Ch0_Timer3 | Ch1_Timer3);
	
#endif
}


/**
 * @brief       TMRClkInit function
 *
 * @param       None
 *
 * @return      None
 *
 * @details     1. 
 */
void TMRClkInit (void)
{
	/* TMR0, TMR1, TMR2, clock selection : 0 -> PCLK, 1 -> LSRC */
		Timer0_clock_PCLK();
	
	/* enable TMR0, TMR1, TMR2 clock divider */
		Timer0_clock_Div_4();
		Timer1_clock_Div_4();
		Timer2_clock_Div_4();
	
	/* enable TMR0, TMR1, TMR2 clock */
		//CLKC->rsbepclkc[1] |= 0x07;
		En_Timer0_clk();
		En_Timer1_clk();
		En_Timer2_clk();
}


/**
 * @brief       IOCFG function
 *
 * @param       None
 *
 * @return      None
 *
 * @details     1. 
 */
void IOCFG( void )
{
	/* enable GPIO clock */
	PORT_PAPBPCPD_Clock_Enable();
	
	/* enable PB.4 PB.5 PB.6 PB.7 output */
	PORT_SetPBPushPull(BIT4 | BIT5 | BIT6 | BIT7);
	
	/* enable PB.4 PB.5 PB.6 PB.7 PWM */
	Set_PB4_PWM0();
	Set_PB5_PWM1();
	Set_PB6_PWM2();
	Set_PB7_PWM3();
	
	/* enable PC.0 PC.1 output */
	PORT_SetPCPushPull(BIT0 | BIT1);
	
	/* enable PC.0 PC.1 PWM */
	Set_PC0_PWM4();
	Set_PC1_PWM5();
	
	/* Set PD1. ,PD2.,PD3 output */
	PORT_SetPDPushPull(BIT1 | BIT2 | BIT3 );
	
	/* Ini LED */
	PD1 = 0; // LED_G1 On
	PD2 = 1 ; //LED_R Off
	PD3= 0;  // LED_G2  On
	
}


/**
 * @brief       main function
 *
 * @param       None
 *
 * @return      None
 *
 * @details     1. 
 *              2.
 */
int main( void )
{
	IOCFG();
	
	/* enable TMR0, TMR1 clock */
	TMRClkInit();
	
	/* TMR0 init */
	TMR0Init();
	
	/* TMR1 init */
	TMR1Init();
	
	/* TMR2 init */
	TMR2Init();
	
	/* enable global interrupt */
	INTC->int_gmask = 0x01;
	
	while(1){
		delay();
	}
}
